package com.ruoyi.project.oms.paeaAuAuditItem.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ruoyi.common.utils.AjaxTool;
import com.ruoyi.common.utils.CommonParaTool;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SdiFilePathTool;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.data.tradeOperate.domain.PaeaDsTradeQuery;
import com.ruoyi.project.er.domain.PaeaErError;
import com.ruoyi.project.er.enums.PaeaErrorSource;
import com.ruoyi.project.er.service.IPaeaErErrorRegisterService;
import com.ruoyi.project.oms.paeaAuAuditItem.enums.AuditItemState;
import com.ruoyi.project.oms.paeaAuAuditItem.model.PaeaAuAuditItemRequest;
import com.ruoyi.project.oms.paeaAuBatch.domain.PaeaAuBatch;
import com.ruoyi.project.oms.paeaAuBatch.enums.AuBatchStatus;
import com.ruoyi.project.oms.paeaAuBatch.mapper.PaeaAuBatchMapper;
import com.ruoyi.project.oms.paeaAuType.domain.PaeaAuType;
import com.ruoyi.project.oms.paeaAuType.service.IPaeaAuTypeService;
import com.ruoyi.project.paea.paeaDsTrade.domain.PaeaDsTrade;
import com.ruoyi.project.paea.paeaDsTrade.service.IPaeaDsTradeService;
import com.ruoyi.project.sdi.scan.enums.AutoErrorDefine;
import com.ruoyi.project.sdi.sdiImage.domain.SdiImage;
import com.ruoyi.project.system.user.domain.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.oms.paeaAuAuditItem.mapper.PaeaAuAuditItemMapper;
import com.ruoyi.project.oms.paeaAuAuditItem.domain.PaeaAuAuditItem;
import com.ruoyi.project.oms.paeaAuAuditItem.service.IPaeaAuAuditItemService;
import com.ruoyi.common.utils.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 【重点监督】Service业务层处理
 *
 * @author ruoyi
 * @date 2020-03-22
 */
@Service
@Slf4j
public class PaeaAuAuditItemServiceImpl extends ServiceImpl<PaeaAuAuditItemMapper, PaeaAuAuditItem> implements IPaeaAuAuditItemService
{
    @Autowired
    private PaeaAuAuditItemMapper paeaAuAuditItemMapper;
    @Autowired
    private PaeaAuBatchMapper paeaAuBatchMapper;
    @Autowired
    private IPaeaDsTradeService paeaDsTradeService;
    @Autowired
    private IPaeaAuTypeService paeaAuTypeService;
    @Autowired
    private IPaeaErErrorRegisterService paeaErErrorRegisterService;
    /**
     * 查询【重点监督】
     *
     * @param id 【重点监督】ID
     * @return 【重点监督】
     */
    @Override
    public PaeaAuAuditItem selectPaeaAuAuditItemById(String id)
    {
        return paeaAuAuditItemMapper.selectPaeaAuAuditItemById(id);
    }

    /**
     * 查询【重点监督】列表
     *
     * @param paeaAuAuditItem 【重点监督】
     * @return 【重点监督】
     */
    @Override
    public List<PaeaAuAuditItem> selectPaeaAuAuditItemList(PaeaAuAuditItem paeaAuAuditItem)
    {
        return paeaAuAuditItemMapper.selectPaeaAuAuditItemList(paeaAuAuditItem);
    }

    /**
     * 新增【重点监督】
     *
     * @param paeaAuAuditItem 【重点监督】
     * @return 结果
     */
    @Override
    public int insertPaeaAuAuditItem(PaeaAuAuditItem paeaAuAuditItem)
    {
        return paeaAuAuditItemMapper.insertPaeaAuAuditItem(paeaAuAuditItem);
    }

    /**
     * 修改【重点监督】
     *
     * @param paeaAuAuditItem 【重点监督】
     * @return 结果
     */
    @Override
    public int updatePaeaAuAuditItem(PaeaAuAuditItem paeaAuAuditItem)
    {
        return paeaAuAuditItemMapper.updatePaeaAuAuditItem(paeaAuAuditItem);
    }

    /**
     * 删除【重点监督】对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deletePaeaAuAuditItemByIds(String ids)
    {
        return paeaAuAuditItemMapper.deletePaeaAuAuditItemByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除【重点监督】信息
     *
     * @param id 【重点监督】ID
     * @return 结果
     */
    @Override
    public int deletePaeaAuAuditItemById(String id)
    {
        return paeaAuAuditItemMapper.deletePaeaAuAuditItemById(id);
    }

    /**
     * 通过batchId查询item
     * @param batchId
     * @return
     */
    @Override
    public List<PaeaAuAuditItem> queryItemForBatchId(String batchId){
        return paeaAuAuditItemMapper.queryItemForBatchId(batchId);
    }

    /**
     * 提交监控
     * @param paeaAuBatch
     * @param paeaAuAuditItem
     * @param state
     * @param errSource
     * @param userCode
     * @return
     */
    @Override
    public String submitItem(PaeaAuBatch paeaAuBatch, PaeaAuAuditItem paeaAuAuditItem,
                             int state, int errSource, String userCode) {
        if (state == AuditItemState.NORMAL_PASS.getCode()) {
            this.passAudit(paeaAuBatch, userCode, paeaAuAuditItem);
        } else if (state == AuditItemState.UN_AUDIT.getCode()) {
            // 删除相关风险
            this.cancelAudit(userCode, paeaAuBatch, paeaAuAuditItem);
        }
        return ("提交成功");
    }

    /**
     * 更新监督批次数
     * @param paeaAuBatch
     * @throws Exception
     */
    @Override
    public void updateBatchCounts(PaeaAuBatch paeaAuBatch){
        int finishedNum = 0;
        // 未监控数
        int unFinishedAuItems = this.queryPaeaAuItemsByState(paeaAuBatch
                .getId(), AuditItemState.UN_AUDIT.getCode(), paeaAuBatch
                .getTrDate());
        if (paeaAuBatch.getAuItemNum().intValue() - unFinishedAuItems > 0) {
            finishedNum = paeaAuBatch.getAuItemNum().intValue() - unFinishedAuItems;
        }
        paeaAuBatch.setFinishNum(finishedNum);
        if (finishedNum > 0) {
            paeaAuBatch.setStatus(String.valueOf(AuBatchStatus.Partially_Audited.getValue()));
        } else if (finishedNum == 0) {
            paeaAuBatch.setStatus(String.valueOf(AuBatchStatus.Initial.getValue()));
        }
        paeaAuBatchMapper.updatePaeaAuBatch(paeaAuBatch);
    }

    /**
     * 批量提交
     * @param paeaAuBatch
     * @param items
     * @param userCode
     * @param queryFlag
     * @return
     */
    @Override
    public int submit(PaeaAuBatch paeaAuBatch, List<PaeaAuAuditItem> items,String userCode, String queryFlag) {
        paeaAuBatch.setAuditorId(userCode);
        // 未监控数
        int unFinishedAuItems = this.queryPaeaAuItemsByState(paeaAuBatch.getId(), AuditItemState.UN_AUDIT.getCode(), paeaAuBatch.getTrDate());
        //已监控数
        paeaAuBatch.setFinishNum(paeaAuBatch.getAuItemNum() - unFinishedAuItems);
        java.sql.Date currentDate = java.sql.Date.valueOf( DateUtils.getDate());
        for (int i = 0; i < items.size(); i++) {
            PaeaAuAuditItem item = items.get(i);
            //批量提交时将PaeaAuAuditItem监督日期修改为当前时间
            item.setAuitDate(new Date(System.currentTimeMillis()));
            // 确定监控
            paeaAuAuditItemMapper.updatePaeaAuAuditItem(item);
        }
        //当全部未监控
        if (unFinishedAuItems == paeaAuBatch.getAuItemNum().intValue()) {
            paeaAuBatch.setStatus(AuBatchStatus.Initial.getValue()+"");
            paeaAuBatch.setFinishDate(null);
            paeaAuBatchMapper.updatePaeaAuBatch(paeaAuBatch);
            return unFinishedAuItems;
        }else{
            //部分监控
            if (unFinishedAuItems != 0) {
                paeaAuBatch.setStatus(AuBatchStatus.Partially_Audited.getValue()+"");
            } else {
                //全部监控
                paeaAuBatch.setStatus(AuBatchStatus.Audited.getValue()+"");
                paeaAuBatch.setFinishDate(new java.sql.Timestamp(System.currentTimeMillis()));
                if (null != paeaAuBatch.getLimitDate()) {
                    // 监控期限 在 当前日期之后 = 已超期
                    if (currentDate.compareTo(paeaAuBatch.getLimitDate()) > 0) {
                        paeaAuBatch.setLimitStatus(2); // 超期
                    } else {
                        paeaAuBatch.setLimitStatus(1); // 正常
                    }
                }
            }
        }
        paeaAuBatchMapper.updatePaeaAuBatch(paeaAuBatch);
        // TODO:写工作日志
        return unFinishedAuItems;
    }

    /**
     * 业务监控模块 通过监控项 重写
     * @param paeaAuBatch
     * @param userCode
     * @param paeaAuAuditItem
     */
    private void passAudit(PaeaAuBatch paeaAuBatch, String userCode,
                           PaeaAuAuditItem paeaAuAuditItem) {
        try {
            paeaAuAuditItem.setState(AuditItemState.NORMAL_PASS.getCode()); // 2 正常
            paeaAuAuditItem.setAuitDate(new java.sql.Date(System.currentTimeMillis()));// 监控日期
            paeaAuAuditItem.setAuditorId(userCode);
            // 确定监控
            this.updatePaeaAuAuditItem(paeaAuAuditItem);
            this.updateBatchCounts(paeaAuBatch);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询监督任务
     * @param batchId
     * @param state
     * @param trDate
     * @return
     */
    private int queryPaeaAuItemsByState(String batchId, int state,java.util.Date trDate) {
        PaeaAuAuditItem paeaAuAuditItem = new PaeaAuAuditItem();
        paeaAuAuditItem.setState(state);
        paeaAuAuditItem.setBatchId(batchId);
        int count = 0;
        List<PaeaAuAuditItem> paeaAuAuditItemList =  paeaAuAuditItemMapper.selectPaeaAuAuditItemList(paeaAuAuditItem);//分表查询？？？
        if(paeaAuAuditItemList != null && paeaAuAuditItemList.size() >0){
            count = paeaAuAuditItemList.size();
        }
        return count;
    }

    /**
     * 业务监控模块 取消监控 重写
     * @param userCode
     * @param paeaAuBatch
     * @param paeaAuAuditItem
     */
    private void cancelAudit(String userCode, PaeaAuBatch paeaAuBatch,
                            PaeaAuAuditItem paeaAuAuditItem) {
        try {
            paeaAuAuditItem.setState(AuditItemState.UN_AUDIT.getCode()); // 2 正常
            paeaAuAuditItem.setAuditorId(userCode);
            paeaAuAuditItem.setAuitDate(new java.sql.Date(System.currentTimeMillis()));
            // 确定监控
            paeaAuAuditItemMapper.updatePaeaAuAuditItem(paeaAuAuditItem);
            this.updateBatchCounts(paeaAuBatch);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过流水查影像
     * @param itemId
     * @return
     */
    public String querySdiImagesByTrade(String itemId) {
        String  paeaAuTypeName = "";
        String taskString = "";
        try {
            /**
             * 基本信息
             */
            PaeaAuAuditItem item = paeaAuAuditItemMapper.selectPaeaAuAuditItemById(itemId);
            String vchNo = item.getVchNo();
            PaeaDsTradeQuery paeaDsTradeQuery = new PaeaDsTradeQuery();
            paeaDsTradeQuery.setTrDate(item.getTrDate());
            paeaDsTradeQuery.setBrCode(item.getOrgId());
            paeaDsTradeQuery.setTrTelr(item.getTellerId());
            paeaDsTradeQuery.setStartVchNo(vchNo);
            paeaDsTradeQuery.setFilterFlag(1);
            //分表查询
            List<PaeaDsTrade> paeaDsTrades = paeaDsTradeService.selectPaeaDsTrades(paeaDsTradeQuery);
            PaeaDsTrade trade = new PaeaDsTrade();
            if (!paeaDsTrades.isEmpty()) {
                trade = (PaeaDsTrade) paeaDsTrades.get(0);
            }
            String id=item.getDsTradeId();
            String paaiInfo1 = AjaxTool.getTaskAjaxString(item);
            paaiInfo1 = paaiInfo1.replace("id","itemId");
            //分表查询
            PaeaDsTrade paeaDsTrade=paeaDsTradeService.selectPaeaDsTradeById(id);
            //添加账号
            String paaiInfo2=AjaxTool.getTaskAjaxString(paeaDsTrade);
            //拼接 item 字段paaiInfo1 和 流水字段paaiInfo2
            String paaiInfo=paaiInfo1+paaiInfo2;
            /**
             * 影像
             */
            String sdiFilePathString = "";
            if (trade.getId() != null) {
                //分表查询
                List<SdiImage> sdiImages = paeaDsTradeService.getSdiImagesByPaeaDsTrade(trade);
                String imagePathPrefix = "";
                if (sdiImages != null && sdiImages.size() > 0) {
//                        imagePathPrefix = CommonParaTool.getImgPathPrefix(sdiImages
//                                .get(0).getAuditOrgCode(), sdiImages.get(0)
//                                .getTrDate());
                    //分表查询
                    imagePathPrefix = CommonParaTool.getImgPathPrefix(sdiImages.get(0).getAuditOrgCode());
                    sdiFilePathString = SdiFilePathTool.toSdiFilePathString(sdiImages, imagePathPrefix);
                }
            }
            /**
             * 监控点
             */
            // 重点监控监控点
            String impInfo = "";
            // 合成信息
            String papInfo = "";
            // 通过监控信息获得流水号
            String txnSeq = item.getTxnSeq();
            PaeaAuType paeaAuType = paeaAuTypeService.selectPaeaAuTypeById(item.getAuTypeId());
            if(paeaAuType != null){
                paeaAuTypeName = paeaAuType.getName();
            }
            papInfo = impInfo;
            /**
             * 返回到页面
             */
            taskString = paaiInfo + AjaxTool.splitCharLevel1
                    + sdiFilePathString + AjaxTool.splitCharLevel1 + papInfo+ "^"+paeaAuTypeName;
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return taskString;
    }

    /**
     * 单笔流水登记缺票
     * @param id
     */
    @Override
    @Transactional
    public void lostVoucherRegister(String id) {
        User user = ShiroUtils.getSysUser();
        //更新流水状态为缺票
        PaeaDsTrade paeaDsTrade = this.paeaDsTradeService.getById(id);
        paeaDsTrade.setStatus(3);//缺票
        paeaDsTradeService.updatePaeaDsTrade(paeaDsTrade);
        //TODO 记录缺票信息到登记缺票表，调用方法

        //创建缺票差错
        this.createLostVoucherError(paeaDsTrade,user);
    }

    /**
     * 创建差错
     * @param paeaDsTrade
     * @param user
     */
    private void createLostVoucherError(PaeaDsTrade paeaDsTrade, User user) {
        PaeaErError paeaErError = new PaeaErError();
        paeaErError.setCreateBy(user.getLoginName());
        paeaErError.setCreateTime(new Date());
        paeaErError.setErrSource(PaeaErrorSource.S重点监控.getValue());
        paeaErError.setTrDate(new java.sql.Date(paeaDsTrade.getTrDate().getTime()));
        paeaErError.setOrgId(paeaDsTrade.getBrCode());
        paeaErError.setTellerId(paeaDsTrade.getTrTelr());
        String errorMessgae = "缺票流水："+paeaDsTrade.getVchNo();
        paeaErError.setAuditProceeding(errorMessgae);
        Date correctLimitDate = CommonParaTool.getCorrectLimitDate();
        paeaErError.setCorrectLimitDate(new java.sql.Date(correctLimitDate.getTime()));

        paeaErError.setTradeId(paeaDsTrade.getImageId());
        paeaErError.setVchNo(paeaDsTrade.getVchNo());
        this.paeaErErrorRegisterService.registerError(paeaErError);
        log.info("日期：" + paeaDsTrade.getTrDate() + " 机构：" + paeaDsTrade.getBrCode() + " 柜员："
                + paeaDsTrade.getTrTelr() + " 风险信息：" + errorMessgae);
    }

}
